import pygame
import random
import sys
import math

# 初始化pygame
pygame.init()

# 定义现代化颜色方案
MUSHROOM_COLORS = [
    (255, 0, 255),   # 紫色蘑菇 - 加速
    (0, 255, 255),   # 青色蘑菇 - 减速
    (255, 255, 0),   # 黄色蘑菇 - 分数加倍
    (255, 165, 0),   # 橙色蘑菇 - 短时间无敌
    (128, 0, 128)    # 深紫色蘑菇 - 长度变化
]
DARK_BG = (40, 44, 52)  # 深色背景
GRID_COLOR = (86, 98, 119)  # 网格颜色
SNAKE_HEAD_COLOR = (97, 175, 239)  # 蛇头蓝色
SNAKE_BODY_COLOR = (152, 195, 121)  # 蛇身绿色
FOOD_COLOR = (224, 108, 117)  # 食物红色
SCORE_COLOR = (198, 120, 221)  # 分数紫色
ACCENT_COLOR = (229, 192, 123)  # 强调色金色
WHITE = (255, 255, 255)  # 白色

# 游戏设置
WIDTH, HEIGHT = 800, 600
GRID_SIZE = 25
GRID_WIDTH = WIDTH // GRID_SIZE
GRID_HEIGHT = HEIGHT // GRID_SIZE
FPS = 12

# 创建游戏窗口
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("现代化贪吃蛇游戏")
clock = pygame.time.Clock()

class Snake:
    def __init__(self):
        self.positions = [(GRID_WIDTH // 2, GRID_HEIGHT // 2)]
        self.direction = (1, 0)  # 初始向右移动
        self.length = 3
        self.score = 0
        self.glow_effect = 0
        self.glow_direction = 1
        self.speed_multiplier = 1.0
        self.invincible = False
        self.invincible_timer = 0
        self.score_multiplier = 1
        self.effect_end_time = 0

    def get_head_position(self):
        return self.positions[0]

    def update(self):
        # 处理效果时间
        current_time = pygame.time.get_ticks()
        if self.effect_end_time > 0 and current_time > self.effect_end_time:
            self.reset_effects()

        # 无敌状态闪烁效果
        if self.invincible:
            self.invincible_timer += 1
            if self.invincible_timer % 5 == 0:
                self.glow_effect = 1 - self.glow_effect

        head = self.get_head_position()
        x, y = self.direction
        new_head = ((head[0] + x) % GRID_WIDTH, (head[1] + y) % GRID_HEIGHT)

        # 检查是否撞到自己（无敌状态下不会撞到自己）
        if not self.invincible and new_head in self.positions[1:]:
            return False

        self.positions.insert(0, new_head)
        if len(self.positions) > self.length:
            self.positions.pop()

        # 更新发光效果
        if not self.invincible:
            self.glow_effect += 0.1 * self.glow_direction
            if self.glow_effect >= 1:
                self.glow_effect = 1
                self.glow_direction = -1
            elif self.glow_effect <= 0:
                self.glow_effect = 0
                self.glow_direction = 1

        return True

    def grow(self):
        self.length += 1
        self.score += int(10 * self.score_multiplier)

    def change_direction(self, direction):
        # 防止直接反向移动
        if (direction[0] * -1, direction[1] * -1) != self.direction:
            self.direction = direction

    def apply_effect(self, effect_type):
        current_time = pygame.time.get_ticks()
        self.effect_end_time = current_time + 5000  # 效果持续5秒

        if effect_type == 0:  # 紫色蘑菇 - 加速
            self.speed_multiplier = 1.5
        elif effect_type == 1:  # 青色蘑菇 - 减速
            self.speed_multiplier = 0.7
        elif effect_type == 2:  # 黄色蘑菇 - 分数加倍
            self.score_multiplier = 2
        elif effect_type == 3:  # 橙色蘑菇 - 短时间无敌
            self.invincible = True
        elif effect_type == 4:  # 深紫色蘑菇 - 长度变化
            self.length = max(3, self.length + random.choice([-2, -1, 1, 2]))

    def reset_effects(self):
        self.speed_multiplier = 1.0
        self.invincible = False
        self.score_multiplier = 1
        self.invincible_timer = 0
        self.effect_end_time = 0

    def draw(self, surface):
        # 绘制效果提示
        effect_bg = pygame.Surface((200, 25), pygame.SRCALPHA)
        effect_bg.fill((*DARK_BG, 200))
        surface.blit(effect_bg, (10, 10))

        effect_text = []
        if self.speed_multiplier > 1:
            effect_text.append("加速!")
        elif self.speed_multiplier < 1:
            effect_text.append("减速!")
        if self.score_multiplier > 1:
            effect_text.append("分数加倍!")
        if self.invincible:
            effect_text.append("无敌!")

        if effect_text:
            font = pygame.font.SysFont('Arial', 16)
            text = font.render(", ".join(effect_text), True, ACCENT_COLOR)
            surface.blit(text, (15, 12))

        # 绘制蛇身
        for i, position in enumerate(self.positions):
            rect = pygame.Rect(position[0] * GRID_SIZE, position[1] * GRID_SIZE, GRID_SIZE, GRID_SIZE)
            
            if i == 0:  # 蛇头
                # 绘制发光效果
                glow_radius = int(3 * self.glow_effect)
                if glow_radius > 0:
                    glow_surface = pygame.Surface((GRID_SIZE + glow_radius * 2, GRID_SIZE + glow_radius * 2), pygame.SRCALPHA)
                    pygame.draw.ellipse(glow_surface, (*SNAKE_HEAD_COLOR, 100), 
                               (0, 0, GRID_SIZE + glow_radius * 2, GRID_SIZE + glow_radius * 2))
                    surface.blit(glow_surface, (position[0] * GRID_SIZE - glow_radius, position[1] * GRID_SIZE - glow_radius))
                
                # 绘制蛇头
                pygame.draw.ellipse(surface, SNAKE_HEAD_COLOR, rect)
                
                # 绘制眼睛
                eye_size = GRID_SIZE // 6
                if self.direction == (1, 0):  # 向右
                    pygame.draw.ellipse(surface, WHITE, 
                               (rect.x + GRID_SIZE - eye_size - 2, rect.y + eye_size, eye_size, eye_size))
                    pygame.draw.ellipse(surface, WHITE, 
                               (rect.x + GRID_SIZE - eye_size - 2, rect.y + GRID_SIZE - eye_size * 2, eye_size, eye_size))
                elif self.direction == (-1, 0):  # 向左
                    pygame.draw.ellipse(surface, WHITE, 
                               (rect.x + 2, rect.y + eye_size, eye_size, eye_size))
                    pygame.draw.ellipse(surface, WHITE, 
                               (rect.x + 2, rect.y + GRID_SIZE - eye_size * 2, eye_size, eye_size))
                elif self.direction == (0, -1):  # 向上
                    pygame.draw.ellipse(surface, WHITE, 
                               (rect.x + eye_size, rect.y + 2, eye_size, eye_size))
                    pygame.draw.ellipse(surface, WHITE, 
                               (rect.x + GRID_SIZE - eye_size * 2, rect.y + 2, eye_size, eye_size))
                elif self.direction == (0, 1):  # 向下
                    pygame.draw.ellipse(surface, WHITE, 
                               (rect.x + eye_size, rect.y + GRID_SIZE - eye_size - 2, eye_size, eye_size))
                    pygame.draw.ellipse(surface, WHITE, 
                               (rect.x + GRID_SIZE - eye_size * 2, rect.y + GRID_SIZE - eye_size - 2, eye_size, eye_size))
            else:  # 蛇身
                # 圆角矩形效果
                pygame.draw.ellipse(surface, SNAKE_BODY_COLOR, rect)

class Food:
    def __init__(self):
        self.position = (0, 0)
        self.rotation = 0
        self.randomize_position()

    def randomize_position(self):
        self.position = (random.randint(0, GRID_WIDTH - 1), random.randint(0, GRID_HEIGHT - 1))

    def draw(self, surface):
        rect = pygame.Rect(self.position[0] * GRID_SIZE, self.position[1] * GRID_SIZE, GRID_SIZE, GRID_SIZE)

        # 绘制旋转的食物（苹果形状）
        center_x = rect.x + GRID_SIZE // 2
        center_y = rect.y + GRID_SIZE // 2

        # 苹果主体
        pygame.draw.circle(surface, FOOD_COLOR, (center_x, center_y), GRID_SIZE // 2 - 2)

        # 苹果茎
        stem_points = [
            (center_x - 1, rect.y + 2),
            (center_x - 1, rect.y + 5),
            (center_x + 1, rect.y + 5),
            (center_x + 1, rect.y + 2)
        ]
        pygame.draw.polygon(surface, (150, 75, 0), stem_points)

        # 苹果叶子
        leaf_points = [
            (center_x + 2, rect.y + 4),
            (center_x + 6, rect.y + 2),
            (center_x + 4, rect.y + 6)
        ]
        pygame.draw.polygon(surface, (152, 195, 121), leaf_points)


class Mushroom:
    def __init__(self):
        self.position = (0, 0)
        self.type = random.randint(0, len(MUSHROOM_COLORS) - 1)
        self.color = MUSHROOM_COLORS[self.type]
        self.duration = 5000  # 蘑菇效果持续时间(毫秒)
        self.spawn_time = pygame.time.get_ticks()
        self.randomize_position()
        self.pulse = 0
        self.pulse_direction = 1

    def randomize_position(self):
        self.position = (random.randint(0, GRID_WIDTH - 1), random.randint(0, GRID_HEIGHT - 1))

    def is_expired(self):
        return pygame.time.get_ticks() - self.spawn_time > 7000  # 蘑菇7秒后消失

    def update(self):
        # 蘑菇脉动效果
        self.pulse += 0.1 * self.pulse_direction
        if self.pulse >= 1:
            self.pulse = 1
            self.pulse_direction = -1
        elif self.pulse <= 0.5:
            self.pulse = 0.5
            self.pulse_direction = 1

    def draw(self, surface):
        rect = pygame.Rect(self.position[0] * GRID_SIZE, self.position[1] * GRID_SIZE, GRID_SIZE, GRID_SIZE)
        center_x = rect.x + GRID_SIZE // 2
        center_y = rect.y + GRID_SIZE // 2

        # 蘑菇主体
        radius = int((GRID_SIZE // 2 - 2) * (0.8 + self.pulse * 0.2))
        pygame.draw.circle(surface, self.color, (center_x, center_y), radius)

        # 蘑菇顶部斑点
        spot_radius = radius // 3
        pygame.draw.circle(surface, WHITE, (center_x - radius//3, center_y - radius//3), spot_radius)
        pygame.draw.circle(surface, WHITE, (center_x + radius//3, center_y), spot_radius)
        pygame.draw.circle(surface, WHITE, (center_x - radius//4, center_y + radius//3), spot_radius)


def draw_grid(surface):
    """绘制现代化网格"""
    for y in range(0, HEIGHT, GRID_SIZE):
        for x in range(0, WIDTH, GRID_SIZE):
            rect = pygame.Rect(x, y, GRID_SIZE, GRID_SIZE)
            pygame.draw.rect(surface, GRID_COLOR, rect, 1)

def show_score(surface, score):
    """显示现代化分数"""
    # 创建渐变背景
    score_bg = pygame.Surface((200, 40), pygame.SRCALPHA)
    score_bg.fill((*DARK_BG, 200))
    surface.blit(score_bg, (WIDTH - 210, 10))
    
    font = pygame.font.SysFont('Arial', 24)
    text = font.render(f'Score: {score}', True, SCORE_COLOR)
    surface.blit(text, (WIDTH - 200, 15))

def show_game_over(surface, score):
    """显示现代化游戏结束界面"""
    # 创建半透明背景
    overlay = pygame.Surface((WIDTH, HEIGHT), pygame.SRCALPHA)
    overlay.fill((*DARK_BG, 200))
    surface.blit(overlay, (0, 0))
    
    font_large = pygame.font.SysFont('Arial', 60)
    font_small = pygame.font.SysFont('Arial', 32)

    game_over_text = font_large.render('GAME OVER', True, FOOD_COLOR)
    score_text = font_small.render(f'Final Score: {score}', True, SCORE_COLOR)
    restart_text = font_small.render('Press R to Restart', True, ACCENT_COLOR)

    surface.blit(game_over_text, (WIDTH // 2 - game_over_text.get_width() // 2, HEIGHT // 3))
    surface.blit(score_text, (WIDTH // 2 - score_text.get_width() // 2, HEIGHT // 2))
    surface.blit(restart_text, (WIDTH // 2 - restart_text.get_width() // 2, HEIGHT // 2 + 60))

    pygame.display.update()

def draw_effect_timer(surface, snake):
    if snake.effect_end_time > 0:
        current_time = pygame.time.get_ticks()
        remaining = max(0, snake.effect_end_time - current_time)
        percentage = remaining / 5000  # 5秒总时长

        timer_rect = pygame.Rect(10, 40, 200, 5)
        pygame.draw.rect(surface, GRID_COLOR, timer_rect)

        fill_rect = pygame.Rect(10, 40, int(200 * percentage), 5)
        if snake.speed_multiplier != 1.0:
            fill_color = MUSHROOM_COLORS[0] if snake.speed_multiplier > 1 else MUSHROOM_COLORS[1]
        elif snake.score_multiplier != 1:
            fill_color = MUSHROOM_COLORS[2]
        elif snake.invincible:
            fill_color = MUSHROOM_COLORS[3]
        else:
            fill_color = MUSHROOM_COLORS[4]

        pygame.draw.rect(surface, fill_color, fill_rect)


def main():
    snake = Snake()
    food = Food()
    mushroom = None
    game_over = False

    while True:
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                if game_over:
                    if event.key == pygame.K_r:
                        # 重新开始游戏
                        snake = Snake()
                        food = Food()
                        mushroom = None
                        game_over = False
                else:
                    if event.key == pygame.K_UP:
                        snake.change_direction((0, -1))
                    elif event.key == pygame.K_DOWN:
                        snake.change_direction((0, 1))
                    elif event.key == pygame.K_LEFT:
                        snake.change_direction((-1, 0))
                    elif event.key == pygame.K_RIGHT:
                        snake.change_direction((1, 0))

        if not game_over:
            # 更新游戏状态
            if not snake.update():
                game_over = True

            # 检查是否吃到食物
            if snake.get_head_position() == food.position:
                snake.grow()
                food.randomize_position()
                # 确保食物不出现在蛇身上
                while food.position in snake.positions:
                    food.randomize_position()

            # 随机生成蘑菇（20%概率）
            if random.random() < 0.2 and mushroom is None:
                mushroom = Mushroom()
                # 确保蘑菇不出现在蛇身上或食物位置
                while mushroom.position in snake.positions or mushroom.position == food.position:
                    mushroom.randomize_position()

            # 绘制游戏
            screen.fill(DARK_BG)
            draw_grid(screen)
            snake.draw(screen)
            food.draw(screen)
            # 绘制蘑菇（如果存在）
            if mushroom:
                if mushroom.is_expired():
                    mushroom = None
                else:
                    mushroom.update()
                    mushroom.draw(screen)
                    # 检查是否吃到蘑菇
                    if snake.get_head_position() == mushroom.position:
                        snake.apply_effect(mushroom.type)
                        mushroom = None
            show_score(screen, snake.score)
            draw_effect_timer(screen, snake)
        else:
            show_game_over(screen, snake.score)

        pygame.display.update()
        clock.tick(FPS * snake.speed_multiplier)

if __name__ == "__main__":
    main()
